﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.IO;

namespace JCW.Common
{

    /// <summary>
    /// 图片处理帮助类，生成缩略图，生成水印、压缩大小
    /// </summary>
    public static class ImageHelper
    {
        #region 获取对比高度
        /// <summary>
        /// 获取对比高度
        /// </summary>
        /// <param name="image"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        private static double Height(Image image, int width)
        {
            double num = image.Width;
            double height = image.Height;
            return ((Convert.ToDouble(width) / num) * height);
        }
        #endregion

        #region 是否回调
        /// <summary>
        /// 是否回调
        /// </summary>
        /// <returns></returns>
        private static bool ThumbnailCallback()
        {
            return true;
        }
        #endregion

        #region 获取图片格式
        /// <summary>
        /// 获取图片格式
        /// </summary>
        /// <param name="ExtName"></param>
        /// <returns></returns>
        private static ImageFormat GetImageFormat(string ExtName)
        {
            ExtName = ExtName.ToLower();
            switch (ExtName)
            {
                case "bmp":
                    return ImageFormat.Bmp;

                case "emf":
                    return ImageFormat.Emf;

                case "exif":
                    return ImageFormat.Exif;

                case "gif":
                    return ImageFormat.Gif;

                case "icon":
                    return ImageFormat.Icon;

                case "jpg":
                    return ImageFormat.Jpeg;

                case "memorybmp":
                    return ImageFormat.MemoryBmp;

                case "png":
                    return ImageFormat.Png;

                case "tiff":
                    return ImageFormat.Tiff;

                case "wmf":
                    return ImageFormat.Wmf;
            }
            return ImageFormat.Jpeg;
        }
        #endregion

        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param>    
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            Image originalImage = Image.FromFile(originalImagePath);

            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case "HW"://指定高宽缩放（可能变形）                
                    break;
                case "W"://指定宽，高按比例                    
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case "H"://指定高，宽按比例
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case "Cut"://指定高宽裁减（不变形）                
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                default:
                    break;
            }

            //新建一个bmp图片
            Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

            //新建一个画板
            Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
                new Rectangle(x, y, ow, oh),
                GraphicsUnit.Pixel);

            try
            {
                //以jpg格式保存缩略图
                bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }
        /// <summary>
        /// 修改成低质量图片
        /// </summary>
        /// <param name="serverFile">要修改的文件地址</param>
        public static void Modity2LowQualityImage(string serverFile)
        {
            GenLowQualityImage(serverFile, serverFile, 0, 0, null);
        }
        /// <summary>
        /// 修改成特定大小格式的图片
        /// </summary>
        /// <param name="serverFile">要修改的文件地址</param>
        /// <param name="width">宽度，如果大于图片的宽度则取图片宽度，如果为0，取原始宽度</param>
        /// <param name="height">高度</param>
        /// <param name="imgFmt">目标图片格式</param>
        public static void Modity2LowQualityImage(string serverFile, int width, int height, ImageFormat imgFmt)
        {
            GenLowQualityImage(serverFile, serverFile, width, height, imgFmt);
        }
        /// <summary>
        /// 生成低质量图片

        /// </summary>
        /// <param name="serverFile">原始地址</param>
        /// <param name="savePathFile">目标地址</param>
        public static void GenLowQualityImage(string serverFile, string savePathFile)
        {
            GenLowQualityImage(serverFile, savePathFile, 0, 0, null);
        }
        /// <summary>
        /// 生成低质量的缩略图，文件格式默认与原始格式一样

        /// </summary>
        /// <param name="serverFile">原始文件位置</param>
        /// <param name="savePathFile">保存目标文件位置</param>
        /// <param name="iWidth">宽度，如果大于图片的宽度则取图片宽度，如果为0，取原始宽度</param>
        /// <param name="iHeight">高度，同宽度</param>
        public static void GenLowQualityImage(string serverFile, string savePathFile, int iWidth, int iHeight)
        {
            GenLowQualityImage(serverFile, savePathFile, iWidth, iHeight, null);
        }
        /// <summary>
        /// 生成低质量的图标文件
        /// </summary>
        /// <param name="serverFile">原始文件位置</param>
        /// <param name="savePathFile">保存目标文件位置</param>
        /// <param name="iWidth">宽度，如果大于图片的宽度则取图片宽度，如果为0，取原始宽度</param>
        /// <param name="iHeight">高度，同宽度</param>
        /// <param name="imgFmt">图片格式，如果null，那么取原始图片的格式</param>
        public static void GenLowQualityImage(string serverFile, string savePathFile, int iWidth, int iHeight, ImageFormat imgFmt)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(serverFile);
            System.Drawing.Image imgThumb = Modify2LowQualityImage(oImg, iWidth, iHeight);
            ImageFormat format = oImg.RawFormat;
            oImg.Dispose();
            //以jpg格式保存缩略图
            File.SetAttributes(savePathFile, FileAttributes.Normal);
            imgThumb.Save(savePathFile, imgFmt == null ? format : imgFmt);
            imgThumb.Dispose();
        }
        /// <summary>
        /// 生成高质量的所略图，文件格式默认与原始格式一样

        /// </summary>
        /// <param name="serverFile">原始文件位置</param>
        /// <param name="savePathFile">保存目标文件位置</param>
        /// <param name="iWidth">宽度，如果大于图片的宽度则取图片宽度，如果为0，取原始宽度</param>
        /// <param name="iHeight">高度，同宽度</param>
        /// <param name="bgColor">背景颜色</param>
        public static void GenHighQualityImage(string serverFile, string savePathFile, int iWidth, int iHeight, Color bgColor)
        {
            GenHighQualityImage(serverFile, savePathFile, iWidth, iHeight, bgColor, null, null, -1, -1);
        }
        /// <summary>
        /// 生成高质量的所略图
        /// </summary>
        /// <param name="serverFile">原始文件位置</param>
        /// <param name="savePathFile">保存目标文件位置</param>
        /// <param name="iWidth">宽度，如果大于图片的宽度则取图片宽度，如果为0，取原始宽度</param>
        /// <param name="iHeight">高度，同宽度</param>
        /// <param name="bgColor">背景颜色</param>
        /// <param name="imgFmt">图片格式，默认与原始文件一样</param>
        /// <param name="writeText">要在图片上写的文本</param>
        /// <param name="textX">位置X</param>
        /// <param name="textY">位置Y</param>
        public static void GenHighQualityImage(string serverFile, string savePathFile, int iWidth, int iHeight, Color bgColor, ImageFormat imgFmt, string writeText, int textX, int textY)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(serverFile);
            Image b = Modity2HighQualityImage(oImg, iWidth, iHeight, bgColor);
            WriteTextOnImage(b, writeText, textX, textY);
            ImageFormat format = oImg.RawFormat;
            oImg.Dispose();
            File.SetAttributes(savePathFile, FileAttributes.Normal);
            b.Save(savePathFile, imgFmt == null ? format : imgFmt);
            b.Dispose();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serverFile"></param>
        /// <param name="logoFile"></param>
        /// <param name="iWidth"></param>
        /// <param name="iHeight"></param>
        public static void ModifyImageWithLogo(string serverFile, string logoFile, int iWidth, int iHeight)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(serverFile);
            Image b = Modity2HighQualityImage(oImg, iWidth, iHeight, Color.White);
            DrawLogoOnImage(b, logoFile, 0, 0);
            ImageFormat format = oImg.RawFormat;
            oImg.Dispose();
            File.SetAttributes(serverFile, FileAttributes.Normal);
            b.Save(serverFile, format);
            b.Dispose();
        }
        /// <summary>
        /// 修改图片
        /// </summary>
        /// <param name="serverFile"></param>
        /// <param name="logoFile"></param>
        public static void ModifyImageWithLogo(string serverFile, string logoFile)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(serverFile);
            Image b = Modity2HighQualityImage(oImg, 0, 0, Color.White);
            DrawLogoOnImage(b, logoFile, 0, 0);
            ImageFormat format = oImg.RawFormat;
            oImg.Dispose();
            File.SetAttributes(serverFile, FileAttributes.Normal);
            b.Save(serverFile, format);
            b.Dispose();
        }
        /// <summary>
        /// 生成高质量的缩略图

        /// </summary>
        /// <param name="serverFile">原始文件位置</param>
        /// <param name="savePathFile">保存目标文件位置</param>
        /// <param name="logoFile">图标文件地址</param>
        /// <param name="iWidth">宽度，如果大于图片的宽度则取图片宽度</param>
        /// <param name="iHeight">高度，同宽度</param>
        /// <param name="bgColor">背景颜色</param>
        /// <param name="imgFmt">图片格式，默认与原始文件一样</param>
        /// <param name="logoX">位置X</param>
        /// <param name="logoY">位置Y</param>
        public static void GenImageWithLogo(string serverFile, string savePathFile, string logoFile, int iWidth, int iHeight, Color bgColor, ImageFormat imgFmt, int logoX, int logoY)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(serverFile);
            Image b = Modity2HighQualityImage(oImg, iWidth, iHeight, bgColor);
            DrawLogoOnImage(b, logoFile, logoX, logoY);
            ImageFormat format = oImg.RawFormat;
            oImg.Dispose();
            File.SetAttributes(savePathFile, FileAttributes.Normal);
            b.Save(savePathFile, imgFmt == null ? format : imgFmt);
            b.Dispose();
        }
        /// <summary>
        /// 在图片上写文字

        /// </summary>
        /// <param name="sourceFile">原始文件位置</param>
        /// <param name="destFile">保存目标文件位置</param>
        /// <param name="text">要在图片上写的文本</param>
        /// <param name="font">字体</param>
        /// <param name="textX">位置X</param>
        /// <param name="textY">位置Y</param>
        public static void WriteTextOnImage(string sourceFile, string destFile, string text, Font font, int textX, int textY)
        {
            System.Drawing.Image oImg = System.Drawing.Image.FromFile(sourceFile);
            Bitmap bitMapImage = new System.Drawing.Bitmap(oImg, oImg.Width, oImg.Height);
            WriteTextOnImage(oImg, text, textX, textY);
            oImg.Dispose();
            File.SetAttributes(destFile, FileAttributes.Normal);
            bitMapImage.Save(destFile);
            bitMapImage.Dispose();
        }
        private static void GetWidthHeight(Image sourceImage, int iWidth, int iHeight, out int width, out int height)
        {
            Image oImg = sourceImage;
            int intwidth = 0, intheight = 0;
            if (iWidth <= 0)
            {
                intwidth = oImg.Width;
            }
            else if (oImg.Width > iWidth)
            {
                intwidth = iWidth;
                intheight = (oImg.Height * iWidth) / oImg.Width;
            }
            else
            {
                intwidth = oImg.Width;
                intheight = oImg.Height;
            }

            if (iHeight <= 0)
            {
                intheight = oImg.Height;
            }
            else if (oImg.Height > iHeight)
            {
                intwidth = (oImg.Width * iHeight) / oImg.Height;
                intheight = iHeight;
            }
            else
            {
                intwidth = oImg.Width;
                intheight = oImg.Height;
            }
            width = intwidth;
            height = intheight;
        }
        /// <summary>
        /// 修改成低质量图片，返回Image对象
        /// </summary>
        /// <param name="sourceImage">原始图像</param>
        /// <param name="iWidth">宽度</param>
        /// <param name="iHeight">高度</param>
        /// <returns>修改后的Image对象</returns>
        private static Image Modify2LowQualityImage(Image sourceImage, int iWidth, int iHeight)
        {
            Image oImg = sourceImage;
            int intwidth = 0, intheight = 0;
            GetWidthHeight(sourceImage, iWidth, iHeight, out intwidth, out intheight);
            System.Drawing.Image imgThumb = oImg.GetThumbnailImage(intwidth, intheight, null, System.IntPtr.Zero);
            return imgThumb;
        }
        private static Image Modity2HighQualityImage(Image sourceImage, int iWidth, int iHeight, Color bgColor)
        {
            Image oImg = sourceImage;
            int intwidth = 0, intheight = 0;
            GetWidthHeight(sourceImage, iWidth, iHeight, out intwidth, out intheight);
            Bitmap b = new Bitmap(intwidth, intheight);
            Graphics g = Graphics.FromImage(b);
            Color myColor = bgColor;
            g.Clear(myColor);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.DrawImage(oImg, new Rectangle(0, 0, intwidth, intheight), new Rectangle(0, 0, oImg.Width, oImg.Height), GraphicsUnit.Pixel);
            return b;
        }
        private static void DrawLogoOnImage(Image sourceImage, string logoFile, int logoX, int logoY)
        {
            Image imgBG = Image.FromFile(logoFile);
            float[][] ptsArray ={ 
                new float[] {1, 0, 0, 0, 0},
                new float[] {0, 1, 0, 0, 0},
                new float[] {0, 0, 1, 0, 0},
                new float[] {0, 0, 0, 0.618f, 0}, 
                new float[] {0, 0, 0, 0, 1}};
            ColorMatrix clrMatrix = new ColorMatrix(ptsArray);
            ImageAttributes imgAttributes = new ImageAttributes();
            imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            Graphics.FromImage(sourceImage).DrawImage(imgBG, new Rectangle(logoX, logoY, imgBG.Width, imgBG.Height), logoX, logoY, imgBG.Width, imgBG.Height, GraphicsUnit.Pixel, imgAttributes);
        }
        private static void WriteTextOnImage(Image sourceImage, string writeText, int textX, int textY)
        {
            int intwidth = sourceImage.Width;
            int intheight = sourceImage.Height;
            if (!String.IsNullOrEmpty(writeText))
            {
                textX = (textX >= 0 && textX <= intwidth) ? textX : 0;
                textY = (textY >= 0 && textY <= intheight) ? textY : 0;
                WriteTextOnImage(Graphics.FromImage(sourceImage), writeText, null, textX, textY);
            }
        }
        private static void WriteTextOnImage(Graphics gra, string text, Font font, int textX, int textY)
        {
            if (font == null)
            {
                font = new Font("宋体", 12, FontStyle.Bold);
            }
            gra.SmoothingMode = SmoothingMode.AntiAlias;
            gra.DrawString(text, font, SystemBrushes.WindowText, new Point(textX, textY));
        }
    }

    #region 生成缩略模式
    /// <summary>
    /// 生成缩略模式
    /// </summary>
    public enum ThumbnailMode
    {
        /// <summary>
        /// 压缩到指定高度和宽度，可能变形
        /// </summary>
        Compress,

        /// <summary>
        /// 适应指定宽度，高度按比例压缩，不变形
        /// </summary>
        FitWidth,

        /// <summary>
        /// 适应指定高度，宽度按比例压缩，不变形
        /// </summary>
        FitHeight,

        /// <summary>
        /// 按指定高度和宽度，剪裁掉多出部分多，不变形
        /// </summary>
        Cut
    }
    #endregion
}